<?php

namespace App\Logic\Order;

use App\Component\LogListForm;
use App\Component\Payment\AlipayApp;
use App\Component\Payment\WechatpayApp;
use App\Core\BaseCore;
use App\Core\BaseForm;
use App\Core\BaseListForm;
use App\Core\BaseModel;
use App\Core\Exception\DefaultException;
use App\Core\Exception\ValidationException;
use App\Core\Output;
use App\Enums\ValidateEnums;
use App\Model\Member\VipModel;
use App\Model\Order\OrderModel;
use App\Model\Order\OrderTaskModel;
use App\Logic\Order\Form\NotifyForm;
use App\Model\Account\CollectionAccountModel;
use App\Util\ArrayHelper;
use App\Util\CommonHelper;
use EasySwoole\Component\Di;
use EasySwoole\Component\Singleton;
use EasySwoole\EasySwoole\Config as ESConfig;
use EasySwoole\Http\Request;
use EasySwoole\ORM\DbManager;
use EasySwoole\ORM\Exception\Exception;
use EasySwoole\Redis\Redis;
use EasySwoole\RedisPool\RedisPool;
use EasySwoole\Utility\Random;
use EasySwoole\Validate\Validate;
use Throwable;
use function PHPUnit\Framework\throwException;

class OrderPaymentService extends BaseCore
{

    use Singleton;


    /**
     * 字典数据
     * @param Request $request
     * @return Output
     * @throws Exception
     * @throws Throwable
     */
    public function getDict(Request $request) : Output
    {
        $payment = \App\Logic\Account\RechargeService::getInstance()->paymentDict($request);
        $vip_list = \App\Logic\Member\VipService::getInstance()->vipDict($request);
        $result = [
            'payment'   => ArrayHelper::keyArrayToList($payment->getData()),
            'vip_list'   => ArrayHelper::keyArrayToList($vip_list->getData()),
            'pay_state_list' => ArrayHelper::keyArrayToList(OrderTaskModel::getPayStateDict()),
            'order_state_list' => ArrayHelper::keyArrayToList(OrderModel::getOrderStateDict())
        ];

        return $this->success($result);
    }

    /**
     * 后台支付 backendPay
     * @param $data
     * @return Output
     * @throws DefaultException
     * @throws Exception
     * @throws Throwable
     * @throws \EasySwoole\Mysqli\Exception\Exception
     */
    public function backendPay($data) : Output
    {
        $payment = CollectionAccountModel::getOne(['id' => $data['payment_id']]);
        if(empty($payment->id)) {
            throw new DefaultException('支付方式错误');
        }
        $payNotify = new NotifyForm([
            'notify_data' => [
                'out_trade_no'   => $data['out_trade_no'],
                'total_fee'      => bcmul($data['total_fee'], 100, 0),
                'success_time'   => $data['success_time'],
                'channel'        => $payment->channel,
                'payment_id'     => $data['payment_id'],
                'transaction_id' => $data['transaction_id']
            ],
        ]);

        $result = $payNotify->payNotify();
        return $result;//$this->success($result);
    }

    public function alipay($data) : Output{
        $payNotify = new NotifyForm([
            'notify_data' => [
                'out_trade_no'   => $data['out_trade_no'],
                'total_fee'      => bcmul($data['total_amount'], 100, 0),
                'success_time'   => $data['gmt_payment'],
                'channel'        => CollectionAccountModel::CHANNEL_MEMBER,
                'payment_id'     => CollectionAccountModel::PAYMENT_ALIPAYAPP,
                'transaction_id' => $data['trade_no']
            ],
        ]);

        $result = $payNotify->payNotify();
        return $result;

    }

    /**
     * 微信支付 wepay
     * @param $data
     * @return Output
     * @throws DefaultException
     * @throws Exception
     * @throws Throwable
     * @throws \EasySwoole\Mysqli\Exception\Exception
     */
    public function wepay($data) : Output{
        $payNotify = new NotifyForm([
            'notify_data' => [
                'out_trade_no'   => $data['out_trade_no'],
                'total_fee'      => $data['amount']['total'],
                'success_time'   => date('Y-m-d H:i:s', strtotime($data['success_time'])),
                'channel'        => CollectionAccountModel::CHANNEL_MEMBER,
                'payment_id'     => CollectionAccountModel::PAYMENT_WXPAYAPP,
                'transaction_id' => $data['transaction_id']
            ],
        ]);

        $result = $payNotify->payNotify();
        return $result;

    }

    /**
     * 用户支付 memberPay
     * @param $data
     * @return String
     * @throws DefaultException
     * @throws Exception
     * @throws Throwable
     * @throws \EasySwoole\Mysqli\Exception\Exception
     */
    public function memberPay($data)
    {
        // 组装快速验证
        $validate = Validate::make([
            'order_id'    => 'required|notEmpty',
            'payment_id' => 'required|notEmpty',
        ], [], [
            'order_id'    => '订单ID',
            'payment_id' => '支付方式',
        ]);

        // 验证结果
        $bool = $validate->validate($data);
        if (!$bool) {
            throw new DefaultException($validate->getError()->__toString());
        }
        $order = OrderModel::getOne(['id' => $data['order_id'], 'pay_state' => 0]);
        if(empty($order->id)) {
            throw new DefaultException('订单错误');
        }
        $vip = VipModel::getOne(['id' => $order->vip_id, 'state' => 1]);
        if(empty($vip->id)) {
            throw new DefaultException('订单VIP错误');
        }
        switch ($data['payment_id']){
            case CollectionAccountModel::PAYMENT_ALIPAYAPP://支付宝app支付
                $result = AlipayApp::getInstance()->pay($data['payment_id'], $data['order_id'], bcdiv(bcmul($order->amount, 100, 0), 100, 2), $vip->name);
                break;
            case CollectionAccountModel::PAYMENT_WXPAYAPP://微信app支付
                $result = WechatpayApp::getInstance()->pay($data['payment_id'], $data['order_id'], bcmul($order->amount, 100, 0), $vip->name);
                break;
            default:
                throw new DefaultException('支付方式错误');
        }

//
        return $result;//$this->success([$result]);
    }


}
